#include "hxPrintf.h"

#include <stdint.h>
#include <math.h>

#if defined(__has_include)
#if __has_include("hxPrintfConfig.h")
#ifndef HX_PRINTF_USE_CONFIG_FILE
#define HX_PRINTF_USE_CONFIG_FILE 1
#endif
#endif
#endif

#if defined(HX_PRINTF_USE_CONFIG_FILE)&&HX_PRINTF_USE_CONFIG_FILE==1

#include "hxPrintfConfig.h"

#else
#warning "not using hxPrintfConfig"
#endif

#if defined(__has_include)
#if __has_include("ScnsConfig.h")
#ifndef HX_PRINTF_SUPPORT_SCNS
#define HX_PRINTF_SUPPORT_SCNS  1
#endif
#endif
#endif
#if defined(HX_PRINTF_SUPPORT_SCNS)&&HX_PRINTF_SUPPORT_SCNS==1

#include "ScnsConfig.h"
#include "ScnsMath.h"
#include "ScnsSmctp.h"

#ifndef HX_PRINTF_SCNS_WAIT
#define HX_PRINTF_SCNS_WAIT             0XFFFFFFFF
#endif

#endif

#ifndef HX_PRINTF_INT32_ENABLE
#define HX_PRINTF_INT32_ENABLE          1
#endif
#ifndef HX_PRINTF_UINT32_ENABLE
#define HX_PRINTF_UINT32_ENABLE         1
#endif
#ifndef HX_PRINTF_INT64_ENABLE
#define HX_PRINTF_INT64_ENABLE          1
#endif
#ifndef HX_PRINTF_UINT64_ENABLE
#define HX_PRINTF_UINT64_ENABLE         1
#endif
#ifndef HX_PRINTF_UINT32_BOX_ENABLE
#define HX_PRINTF_UINT32_BOX_ENABLE     1
#endif
#ifndef HX_PRINTF_UINT64_BOX_ENABLE
#define HX_PRINTF_UINT64_BOX_ENABLE     1
#endif
#ifndef HX_PRINTF_FLOAT_ENABLE
#define HX_PRINTF_FLOAT_ENABLE          1
#endif
#ifndef HX_PRINTF_CHAR_ENABLE
#define HX_PRINTF_CHAR_ENABLE           1
#endif
#ifndef HX_PRINTF_STRING_ENABLE
#define HX_PRINTF_STRING_ENABLE         1
#endif
#ifndef HX_PRINTF_ARRAY_ENABLE
#define HX_PRINTF_ARRAY_ENABLE          1
#endif
#ifndef HX_PRINTF_ARRAY_INT8_ENABLE
#define HX_PRINTF_ARRAY_INT8_ENABLE     1
#endif
#ifndef HX_PRINTF_ARRAY_UINT8_ENABLE
#define HX_PRINTF_ARRAY_UINT8_ENABLE    1
#endif
#ifndef HX_PRINTF_ARRAY_INT16_ENABLE
#define HX_PRINTF_ARRAY_INT16_ENABLE    1
#endif
#ifndef HX_PRINTF_ARRAY_UINT16_ENABLE
#define HX_PRINTF_ARRAY_UINT16_ENABLE   1
#endif
#ifndef HX_PRINTF_ARRAY_INT32_ENABLE
#define HX_PRINTF_ARRAY_INT32_ENABLE    1
#endif
#ifndef HX_PRINTF_ARRAY_UINT32_ENABLE
#define HX_PRINTF_ARRAY_UINT32_ENABLE   1
#endif
#ifndef HX_PRINTF_ARRAY_INT64_ENABLE
#define HX_PRINTF_ARRAY_INT64_ENABLE    1
#endif
#ifndef HX_PRINTF_ARRAY_UINT64_ENABLE
#define HX_PRINTF_ARRAY_UINT64_ENABLE   1
#endif
#ifndef HX_PRINTF_ARRAY_FLOAT_ENABLE
#define HX_PRINTF_ARRAY_FLOAT_ENABLE    1
#endif
#ifndef HX_PRINTF_ARRAY_CHAR_ENABLE
#define HX_PRINTF_ARRAY_CHAR_ENABLE     1
#endif
#ifndef HX_PRINTF_FLS_ENABLE
#define HX_PRINTF_FLS_ENABLE            1
#endif
#ifndef HX_PRINTF_32_AS_64
#define HX_PRINTF_32_AS_64            0
#endif

typedef void (*OutFunc)(char character,void*ptr,size_t idx);

typedef struct
{
    void (*fct)(char character,void*arg,size_t idx);
    void*arg;
}OutFuncWrap;

typedef struct
{
    char*buffer;
    size_t maxLen;
}OutBufWrap;

typedef struct
{
    const char*file;
    int line;
    int length;
    char prevBuf;
}FileLineStruct;

#ifndef __always_inline
#define    __always_inline    __inline__ __attribute__((__always_inline__,always_inline))
#endif

static __always_inline unsigned int __isfinite__(double x){return isfinite(x);}

static __always_inline unsigned int __fpclassify__(double x){return fpclassify(x);}


#define EXTERNAL_TEXT(x) __attribute__((section(".text.hxPrintf" #x)))
#define INTERNAL_TEXT(x) __attribute__((section(".text.hxPrintf" #x))) static

INTERNAL_TEXT(outBuf) void outBuf(char character,void*ptr,size_t idx)
{
    if(idx<((OutBufWrap*)ptr)->maxLen)
    {
        ((char*)((OutBufWrap*)ptr)->buffer)[idx]=character;
    }
}

/**
* internal null output
* @param character
* @param ptr
*/
INTERNAL_TEXT(outNull) void outNull(char character,void*ptr,size_t idx)
{
    (void)character;
    (void)ptr;
    (void)idx;
}
/**
* internal put char wrapper
* @param character
* @param ptr
*/
INTERNAL_TEXT(outChar) void outChar(char character,void*ptr,size_t idx)
{
    (void)ptr;
    (void)idx;
    if(character)
    {
#if defined(SCNS_SMCTP_ENABLE)&&SCNS_SMCTP_ENABLE==1
        scnsSmctpPutCharUnsafe(SCNS_SMCTP_CHANNEL_DEBUG,character,HX_PRINTF_SCNS_WAIT);
#elif defined(hxPrintfPutchar)
        hxPrintfPutchar(character);
#elif defined (_WIN32)||defined(__APPLE__)||defined(__linux__)
        putchar(character);
#else
#warning "no putchar defined"
#endif
    }
}

#if defined (_WIN32)||defined(__APPLE__)||defined(__linux__)

INTERNAL_TEXT(outFChar) void outFChar(char character,void*ptr,size_t idx)
{
    (void)idx;
    if(character)
    {
        putc(character,(FILE*)ptr);
    }
}

#endif

/*
INTERNAL_TEXT(outFunc) void outFunc(char character,void*ptr,size_t idx)
{
    (void)idx;
    if(character)
    {
        ((OutFuncWrap*)ptr)->fct(character,((OutFuncWrap*)ptr)->arg,idx);
    }
}
*/
INTERNAL_TEXT(getUintFromStr) unsigned int getUintFromStr(const char**str)
{
    unsigned int ans=0;
    for(char c;(c=**str)>='0'&&c<='9';ans=(ans<<3)+(ans<<1)+c-'0',(*str)++){}
    return ans;
}

#if !(defined(SCNS_MATH_ENABLE)&&SCNS_MATH_ENABLE)

INTERNAL_TEXT(scnsLog10FloorUint32) uint8_t scnsLog10FloorUint32(uint32_t x)
{
//@formatter:off
    if(x<0X186A0ULL){if(x<0X3E8ULL){if(x<0X64ULL){if(x<0XAULL){return 0;}else{return 1;}}else{return 2;}}else{if(x<0X2710ULL){return 3;}else{return 4;}}}else{if(x<0X5F5E100ULL){if(x<0X989680ULL){if(x<0XF4240ULL){return 5;}else{return 6;}}else{return 7;}}else{if(x<0X3B9ACA00ULL){return 8;}else{return 9;}}}
//@formatter:on
}

INTERNAL_TEXT(scnsLog10FloorUint64) uint8_t scnsLog10FloorUint64(uint64_t x)
{
//@formatter:off
    if(x<0X2540BE400ULL){if(x<0X186A0ULL){if(x<0X3E8ULL){if(x<0X64ULL){if(x<0XAULL){return 0;}else{return 1;}}else{return 2;}}else{if(x<0X2710ULL){return 3;}else{return 4;}}}else{if(x<0X5F5E100ULL){if(x<0X989680ULL){if(x<0XF4240ULL){return 5;}else{return 6;}}else{return 7;}}else{if(x<0X3B9ACA00ULL){return 8;}else{return 9;}}}}else{if(x<0X38D7EA4C68000ULL){if(x<0X9184E72A000ULL){if(x<0XE8D4A51000ULL){if(x<0X174876E800ULL){return 10;}else{return 11;}}else{return 12;}}else{if(x<0X5AF3107A4000ULL){return 13;}else{return 14;}}}else{if(x<0XDE0B6B3A7640000ULL){if(x<0X16345785D8A0000ULL){if(x<0X2386F26FC10000ULL){return 15;}else{return 16;}}else{return 17;}}else{if(x<0X8AC7230489E80000ULL){return 18;}else{return 19;}}}}
//@formatter:on
}

INTERNAL_TEXT(scnsLog2FloorUint32) uint8_t scnsLog2FloorUint32(uint32_t x)
{
//@formatter:off
    if(x<0X10000ULL){if(x<0X100ULL){if(x<0X10ULL){if(x<0X4ULL){if(x<0X2ULL){return 0;}else{return 1;}}else{if(x<0X8ULL){return 2;}else{return 3;}}}else{if(x<0X40ULL){if(x<0X20ULL){return 4;}else{return 5;}}else{if(x<0X80ULL){return 6;}else{return 7;}}}}else{if(x<0X1000ULL){if(x<0X400ULL){if(x<0X200ULL){return 8;}else{return 9;}}else{if(x<0X800ULL){return 10;}else{return 11;}}}else{if(x<0X4000ULL){if(x<0X2000ULL){return 12;}else{return 13;}}else{if(x<0X8000ULL){return 14;}else{return 15;}}}}}else{if(x<0X1000000ULL){if(x<0X100000ULL){if(x<0X40000ULL){if(x<0X20000ULL){return 16;}else{return 17;}}else{if(x<0X80000ULL){return 18;}else{return 19;}}}else{if(x<0X400000ULL){if(x<0X200000ULL){return 20;}else{return 21;}}else{if(x<0X800000ULL){return 22;}else{return 23;}}}}else{if(x<0X10000000ULL){if(x<0X4000000ULL){if(x<0X2000000ULL){return 24;}else{return 25;}}else{if(x<0X8000000ULL){return 26;}else{return 27;}}}else{if(x<0X40000000ULL){if(x<0X20000000ULL){return 28;}else{return 29;}}else{if(x<0X80000000ULL){return 30;}else{return 31;}}}}}
//@formatter:on
}

INTERNAL_TEXT(scnsLog2FloorUint64) uint8_t scnsLog2FloorUint64(uint64_t x)
{
//@formatter:off
    if(x<0X100000000ULL){if(x<0X10000ULL){if(x<0X100ULL){if(x<0X10ULL){if(x<0X4ULL){if(x<0X2ULL){return 0;}else{return 1;}}else{if(x<0X8ULL){return 2;}else{return 3;}}}else{if(x<0X40ULL){if(x<0X20ULL){return 4;}else{return 5;}}else{if(x<0X80ULL){return 6;}else{return 7;}}}}else{if(x<0X1000ULL){if(x<0X400ULL){if(x<0X200ULL){return 8;}else{return 9;}}else{if(x<0X800ULL){return 10;}else{return 11;}}}else{if(x<0X4000ULL){if(x<0X2000ULL){return 12;}else{return 13;}}else{if(x<0X8000ULL){return 14;}else{return 15;}}}}}else{if(x<0X1000000ULL){if(x<0X100000ULL){if(x<0X40000ULL){if(x<0X20000ULL){return 16;}else{return 17;}}else{if(x<0X80000ULL){return 18;}else{return 19;}}}else{if(x<0X400000ULL){if(x<0X200000ULL){return 20;}else{return 21;}}else{if(x<0X800000ULL){return 22;}else{return 23;}}}}else{if(x<0X10000000ULL){if(x<0X4000000ULL){if(x<0X2000000ULL){return 24;}else{return 25;}}else{if(x<0X8000000ULL){return 26;}else{return 27;}}}else{if(x<0X40000000ULL){if(x<0X20000000ULL){return 28;}else{return 29;}}else{if(x<0X80000000ULL){return 30;}else{return 31;}}}}}}else{if(x<0X1000000000000ULL){if(x<0X10000000000ULL){if(x<0X1000000000ULL){if(x<0X400000000ULL){if(x<0X200000000ULL){return 32;}else{return 33;}}else{if(x<0X800000000ULL){return 34;}else{return 35;}}}else{if(x<0X4000000000ULL){if(x<0X2000000000ULL){return 36;}else{return 37;}}else{if(x<0X8000000000ULL){return 38;}else{return 39;}}}}else{if(x<0X100000000000ULL){if(x<0X40000000000ULL){if(x<0X20000000000ULL){return 40;}else{return 41;}}else{if(x<0X80000000000ULL){return 42;}else{return 43;}}}else{if(x<0X400000000000ULL){if(x<0X200000000000ULL){return 44;}else{return 45;}}else{if(x<0X800000000000ULL){return 46;}else{return 47;}}}}}else{if(x<0X100000000000000ULL){if(x<0X10000000000000ULL){if(x<0X4000000000000ULL){if(x<0X2000000000000ULL){return 48;}else{return 49;}}else{if(x<0X8000000000000ULL){return 50;}else{return 51;}}}else{if(x<0X40000000000000ULL){if(x<0X20000000000000ULL){return 52;}else{return 53;}}else{if(x<0X80000000000000ULL){return 54;}else{return 55;}}}}else{if(x<0X1000000000000000ULL){if(x<0X400000000000000ULL){if(x<0X200000000000000ULL){return 56;}else{return 57;}}else{if(x<0X800000000000000ULL){return 58;}else{return 59;}}}else{if(x<0X4000000000000000ULL){if(x<0X2000000000000000ULL){return 60;}else{return 61;}}else{if(x<0X8000000000000000ULL){return 62;}else{return 63;}}}}}}
//@formatter:on
}

INTERNAL_TEXT(scnsQPowUint32) uint32_t scnsQPowUint32(uint32_t a,uint32_t n)
{
    uint32_t ans=1;
    while(n)
    {
        if(n&1){ans*=a;}
        a*=a;
        n>>=1;
    }
    return ans;
}

INTERNAL_TEXT(scnsQPowUint64) uint64_t scnsQPowUint64(uint64_t a,uint32_t n)
{
    uint64_t ans=1;
    while(n)
    {
        if(n&1){ans*=a;}
        a*=a;
        n>>=1;
    }
    return ans;
}

INTERNAL_TEXT(scnsQPowFloat) float scnsQPowFloat(float a,uint32_t n)
{
    float ans=1;
    while(n)
    {
        if(n&1){ans*=a;}
        a*=a;
        n>>=1;
    }
    return ans;
}

INTERNAL_TEXT(scnsQPowDouble) double scnsQPowDouble(double a,uint32_t n)
{
    double ans=1;
    while(n)
    {
        if(n&1){ans*=a;}
        a*=a;
        n>>=1;
    }
    return ans;
}

#endif
// internal flag definitions
#define FLAGS_ZEROPAD   (1U<<0U)
#define FLAGS_LEFT      (1U<<1U)
#define FLAGS_PLUS      (1U<<2U)
#define FLAGS_SPACE     (1U<<3U)
#define FLAGS_HASH      (1U<<4U)
#define FLAGS_PRECISION (1U<<5U)
#define FLAGS_ARR_LEN   (1U<<6U)
#define FLAGS_RECURE    (1U<<7U)
#define FLAGS_UPPER     (1U<<8U)
#define FLAGS_H         (1U<<9U)
#define FLAGS_HH        (1U<<10U)

INTERNAL_TEXT(printFlsAfter) size_t printFlsAfter(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,char c);

#define outFls(a,b,d)   do{const char __c=(a);outI=printFlsAfter(out,ptr,outI,fls,__c);out(__c,b,d);}while(0)

INTERNAL_TEXT(printPad) size_t printPad(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,int n,char c)
{
    for(int i=0;i<n;++i)
    {
        outFls(c,ptr,outI);
        ++outI;
    }
    return outI;
}

#if HX_PRINTF_INT64_ENABLE==1

INTERNAL_TEXT(printInt64) size_t printInt64(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,int64_t dat,unsigned int width,unsigned int flags)
{
    const uint8_t f=dat<0;
    const uint64_t datt=(f)?(-dat):(dat);
    const uint8_t numLen=scnsLog10FloorUint64(datt)+1;
    const uint8_t fLen=(f||(flags&FLAGS_PLUS)||(flags&FLAGS_SPACE))?1:0;
    const uint8_t totLen=numLen+fLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if(fLen)
    {
        outFls(f?'-':((flags&FLAGS_SPACE)?' ':'+'),ptr,outI);
        ++outI;
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    uint64_t n=scnsQPowUint64(10,numLen-1);
    for(unsigned int i=0;i<numLen;++i)
    {
        outFls(datt/n%10+'0',ptr,outI);
        ++outI;
        n/=10;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
}

#endif
#if HX_PRINTF_UINT64_ENABLE==1

INTERNAL_TEXT(printUInt64) size_t printUInt64(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,uint64_t datt,unsigned int width,unsigned int flags)
{
    const uint8_t numLen=scnsLog10FloorUint64(datt)+1;
    const uint8_t totLen=numLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    uint64_t n=scnsQPowUint64(10,numLen-1);
    for(unsigned int i=0;i<numLen;++i)
    {
        outFls(datt/n%10+'0',ptr,outI);
        ++outI;
        n/=10;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
}

#endif
#if HX_PRINTF_INT32_ENABLE==1

INTERNAL_TEXT(printInt32) size_t printInt32(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,int32_t dat,unsigned int width,unsigned int flags)
{
#if HX_PRINTF_32_AS_64==1&&HX_PRINTF_INT64_ENABLE==1
    return printInt64(out,ptr,outI,fls,dat,width,flags);
#else
    const uint8_t f=dat<0;
    const uint32_t datt=(f)?(-dat):(dat);
    const uint8_t numLen=scnsLog10FloorUint32(datt)+1;
    const uint8_t fLen=(f||(flags&FLAGS_PLUS)||(flags&FLAGS_SPACE))?1:0;
    const uint8_t totLen=numLen+fLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if(fLen)
    {
        outFls(f?'-':((flags&FLAGS_SPACE)?' ':'+'),ptr,outI);
        ++outI;
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    uint32_t n=scnsQPowUint32(10,numLen-1);
    for(unsigned int i=0;i<numLen;++i)
    {
        outFls(datt/n%10+'0',ptr,outI);
        ++outI;
        n/=10;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
#endif
}

#endif
#if HX_PRINTF_UINT32_ENABLE==1

INTERNAL_TEXT(printUInt32) size_t printUInt32(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,uint32_t datt,unsigned int width,unsigned int flags)
{
#if HX_PRINTF_32_AS_64==1&&HX_PRINTF_UINT64_ENABLE==1
    return printUInt64(out,ptr,outI,fls,datt,width,flags);
#else
    const uint8_t numLen=scnsLog10FloorUint32(datt)+1;
    const uint8_t totLen=numLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    uint32_t n=scnsQPowUint32(10,numLen-1);
    for(unsigned int i=0;i<numLen;++i)
    {
        outFls(datt/n%10+'0',ptr,outI);
        ++outI;
        n/=10;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
#endif
}

#endif
#if HX_PRINTF_UINT64_BOX_ENABLE==1

INTERNAL_TEXT(printUInt64BOX) size_t printUInt64BOX(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,uint64_t datt,unsigned int width,unsigned int flags,uint8_t base)
{
    const uint8_t log2=scnsLog2FloorUint64(datt);
    const uint8_t numLen=log2/base+1;
    const uint8_t fLen=((flags&FLAGS_HASH))?(base==3?1:2):0;
    const uint8_t totLen=numLen+fLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if((flags&FLAGS_HASH))
    {
        outFls('0',ptr,outI);
        ++outI;
        if(base==1)
        {
            outFls('b',ptr,outI);
            ++outI;
        }
        else if(base==4)
        {
            out((flags&FLAGS_UPPER)?'X':'x',ptr,outI);
            ++outI;
        }
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    const char plus=((flags&FLAGS_UPPER)?'A':'a')-10;
    const unsigned int mask=((1U<<base)-1);
    for(unsigned int i=0;i<numLen;++i)
    {
        unsigned int x=(datt>>(base*(numLen-1-i)))&mask;
        out((x<=9)?(x+'0'):(x+plus),ptr,outI);
        ++outI;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
}

#endif
#if HX_PRINTF_UINT32_BOX_ENABLE==1

INTERNAL_TEXT(printUInt32BOX) size_t printUInt32BOX(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,uint32_t datt,unsigned int width,unsigned int flags,uint8_t base)
{
#if HX_PRINTF_32_AS_64==1&&HX_PRINTF_UINT64_BOX_ENABLE==1
    return printUInt64BOX(out,ptr,outI,fls,datt,width,flags,base);
#else
    const uint8_t log2=scnsLog2FloorUint32(datt);
    const uint8_t numLen=log2/base+1;
    const uint8_t fLen=((flags&FLAGS_HASH))?(base==3?1:2):0;
    const uint8_t totLen=numLen+fLen;
    if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    if((flags&FLAGS_HASH))
    {
        outFls('0',ptr,outI);
        ++outI;
        if(base==1)
        {
            outFls('b',ptr,outI);
            ++outI;
        }
        else if(base==4)
        {
            out((flags&FLAGS_UPPER)?'X':'x',ptr,outI);
            ++outI;
        }
    }
    if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,'0');
    }
    const char plus=((flags&FLAGS_UPPER)?'A':'a')-10;
    for(unsigned int i=0;i<numLen;++i)
    {
        unsigned int x=(datt>>(base*(numLen-1-i)))&((1U<<base)-1);
        out((x<=9)?(x+'0'):(x+plus),ptr,outI);
        ++outI;
    }
    if(((flags&FLAGS_LEFT)))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
#endif
}

#endif
#if HX_PRINTF_FLOAT_ENABLE==1

INTERNAL_TEXT(printFloat) size_t printFloat(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,double dat,unsigned int width,int pointNum,unsigned int flags)
{
    const int limitWidth=(width)?width:10;
    if(!(flags&FLAGS_PRECISION)){pointNum=6;}
    switch(__fpclassify__(dat))
    {
        case FP_INFINITE:
        {
            if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            if(signbit(dat))
            {
                outFls('-',ptr,outI);
                ++outI;
            }
            outFls('i',ptr,outI);
            ++outI;
            outFls('n',ptr,outI);
            ++outI;
            outFls('f',ptr,outI);
            ++outI;
            if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            break;
        }
        case FP_NAN:
        {
            if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            outFls('n',ptr,outI);
            ++outI;
            outFls('a',ptr,outI);
            ++outI;
            outFls('n',ptr,outI);
            ++outI;
            if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            break;
        }
        case FP_ZERO:
        {
            const int actualLen=1+(pointNum==0?0:(1+pointNum));
            if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-actualLen,' ');}
            outFls('0',ptr,outI);
            ++outI;
            if(pointNum)
            {
                outFls('.',ptr,outI);
                ++outI;
                while(pointNum--)
                {
                    outFls('0',ptr,outI);
                    ++outI;
                }
            }
            if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-actualLen,' ');}
            break;
        }
        case FP_SUBNORMAL:
        {
            if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            outFls('s',ptr,outI);
            ++outI;
            outFls('u',ptr,outI);
            ++outI;
            outFls('b',ptr,outI);
            ++outI;
            if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
            break;
        }
        case FP_NORMAL:
        {
            static const double log2_10=3.321928094887362f;
            const uint8_t f=signbit(dat)?1:0;
            const int16_t num2=log2_10*(limitWidth-f);
            const int16_t num2_neg=log2_10*(limitWidth-2-f);
            int a=0;
            const double x=frexp(dat,&a);
            (void)x;
            if(f){dat=-dat;}
            //计算整数部分
            uint64_t zhengshu=dat;
            double xiaoshuFloat=dat-zhengshu;
            if(a<num2&&a>-num2_neg&&a<60&&a>-pointNum*log2_10&&pointNum>=0)
            {
                const int zsLen=scnsLog10FloorUint64(zhengshu)+1;
                const int actualLen=f+zsLen+(pointNum==0?0:(1+pointNum));
                if((!(flags&FLAGS_LEFT))&&(!(flags&FLAGS_ZEROPAD))){outI=printPad(out,ptr,outI,fls,((int)width)-actualLen,' ');}
                if(f)
                {
                    outFls('-',ptr,outI);
                    ++outI;
                }
                if((!(flags&FLAGS_LEFT))&&(flags&FLAGS_ZEROPAD)){outI=printPad(out,ptr,outI,fls,((int)width)-actualLen,'0');}
                outI=printUInt64(out,ptr,outI,fls,zhengshu,0,0);
                if(flags&FLAGS_RECURE){pointNum=((int)width)-zsLen-1;}
                if(pointNum<0){pointNum=0;}
                if(pointNum)
                {
                    xiaoshuFloat*=scnsQPowFloat(10,pointNum);
                    const uint64_t xiaoshu=xiaoshuFloat;
                    outFls('.',ptr,outI);
                    ++outI;
                    outI=printUInt64(out,ptr,outI,fls,xiaoshu,pointNum,FLAGS_ZEROPAD);
                }
                if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-actualLen,' ');}
            }
            else
            {
                int16_t expn=(int16_t)((double)floorf(a/log2_10));
                if(expn>=0)
                {
                    dat=(double)(((double)dat)*scnsQPowDouble(0.1,expn));
                    if(!__isfinite__(dat))
                    {
                        if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
                        outFls('s',ptr,outI);
                        ++outI;
                        outFls('u',ptr,outI);
                        ++outI;
                        outFls('b',ptr,outI);
                        ++outI;
                        if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
                    }
                    else
                    {
                        if(dat<1)
                        {
                            expn-=1;
                            dat*=10;
                        }
                        const int16_t expnLen=scnsLog10FloorUint32(expn)+1;
                        int16_t restLen=((int)width)-expnLen-1-f;
                        if(restLen<0){restLen=0;}
                        if(f)
                        {
                            outFls('-',ptr,outI);
                            ++outI;
                        }
                        outI=printFloat(out,ptr,outI,fls,dat,restLen,0,FLAGS_RECURE);
                        outFls('e',ptr,outI);
                        ++outI;
                        outI=printInt32(out,ptr,outI,fls,expn,0,0);
                    }
                }
                else
                {

                    expn=-expn;
                    dat=(double)(((double)dat)*scnsQPowDouble(10,expn));
                    if(!__isfinite__(dat))
                    {
                        if(!((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
                        outFls('s',ptr,outI);
                        ++outI;
                        outFls('u',ptr,outI);
                        ++outI;
                        outFls('b',ptr,outI);
                        ++outI;
                        if(((flags&FLAGS_LEFT))){outI=printPad(out,ptr,outI,fls,((int)width)-3,' ');}
                    }
                    else
                    {
                        if(dat<1)
                        {
                            expn+=1;
                            dat*=10;
                        }
                        const int16_t expnLen=scnsLog10FloorUint32(expn)+1;
                        int16_t restLen=((int)width)-expnLen-2-f;
                        if(restLen<0){restLen=0;}
                        if(f)
                        {
                            outFls('-',ptr,outI);
                            ++outI;
                        }
                        outI=printFloat(out,ptr,outI,fls,dat,restLen,0,FLAGS_RECURE);
                        outFls('e',ptr,outI);
                        ++outI;
                        outFls('-',ptr,outI);
                        ++outI;
                        outI=printInt32(out,ptr,outI,fls,expn,0,0);
                    }
                }
            }
            break;
        }
        default:
        {
            outFls('N',ptr,outI);
            ++outI;
            outFls('/',ptr,outI);
            ++outI;
            outFls('A',ptr,outI);
            ++outI;
        }
    }
    return outI;
}

#endif
#if HX_PRINTF_CHAR_ENABLE

INTERNAL_TEXT(printChar) size_t printChar(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,char c,unsigned int width,unsigned int flags)
{
    const unsigned int totLen=1U;
    if(!(flags&FLAGS_LEFT))
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    outFls(c,ptr,outI);
    ++outI;
    if(flags&FLAGS_LEFT)
    {
        outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
    }
    return outI;
}

#endif
#if HX_PRINTF_STRING_ENABLE

INTERNAL_TEXT(printString) size_t printString(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,const char*p,unsigned int width,unsigned int flags)
{
    if(p)
    {
        unsigned int totLen=0;
        while(p[totLen]){++totLen;}
        if(!(flags&FLAGS_LEFT))
        {
            outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
        }
        char lastC=0;
        while((*p!=0))
        {
            char c=*(p++);
            if((flags&FLAGS_UPPER))
            {
                if(c!='\r')
                {
                    if(!(c=='\n'&&lastC=='\n'))
                    {
                        outFls(c,ptr,outI);
                        ++outI;
                    }
                    lastC=c;
                }
            }
            else
            {
                outFls(c,ptr,outI);
                ++outI;
            }
        }
        if(flags&FLAGS_LEFT)
        {
            outI=printPad(out,ptr,outI,fls,((int)width)-totLen,' ');
        }
    }
    return outI;
}

#endif
#if HX_PRINTF_FLS_ENABLE

INTERNAL_TEXT(printFlsAfter) size_t printFlsAfter(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,char c)
{
    if(fls&&c)
    {
        if(fls->prevBuf=='\n')
        {
            outI=printPad(out,ptr,outI,NULL,fls->length,' ');
            out('|',ptr,outI);
            ++outI;
        }
        else if(fls->prevBuf==0)
        {
            if(fls->file==NULL)
            {
                outI=printPad(out,ptr,outI,NULL,fls->length,' ');
                out('|',ptr,outI);
                ++outI;
            }
            else
            {
                outI=printString(out,ptr,outI,NULL,fls->file,12,0);
                out(':',ptr,outI);
                ++outI;
                outI=printInt32(out,ptr,outI,NULL,fls->line,5,0);
                out('|',ptr,outI);
                ++outI;
            }
        }
        fls->prevBuf=c;
    }
    return outI;
}

#else

INTERNAL_TEXT(printFlsAfter) size_t printFlsAfter(OutFunc out,void*ptr,size_t outI,FileLineStruct*fls,char c)
{
    (void)out;
    (void)ptr;
    (void)fls;
    (void)c;
    return outI;
}

#endif

#if HX_PRINTF_ARRAY_ENABLE==1
#define printARR(T,F)       do{const T*arr=va_arg(va,T*);for(unsigned int i=0;i<arrSize;++i){if(i!=0&&i%arrWidth==0){outFls('\n',ptr,outI);++outI;}outI=F(out,ptr,outI,fls,arr[i],width,flags);outFls(' ',ptr,outI);++outI;}}while(0)
#define printARRBOX(T,F,B)  do{const T*arr=va_arg(va,T*);for(unsigned int i=0;i<arrSize;++i){if(i!=0&&i%arrWidth==0){outFls('\n',ptr,outI);++outI;}outI=F(out,ptr,outI,fls,arr[i],width,flags,B);outFls(' ',ptr,outI);++outI;}}while(0)
#define printARRFLO(T,F)    do{const T*arr=va_arg(va,T*);for(unsigned int i=0;i<arrSize;++i){if(i!=0&&i%arrWidth==0){outFls('\n',ptr,outI);++outI;}outI=F(out,ptr,outI,fls,arr[i],width,precision,flags);outFls(' ',ptr,outI);++outI;}}while(0)
#endif

INTERNAL_TEXT(hxInnerPrintf) int hxInnerPrintf(OutFunc out,void*ptr,FileLineStruct*fls,const char*format,va_list va)
{
    if(!out){out=outNull;}

    unsigned int flags,width,precision;
#if HX_PRINTF_ARRAY_ENABLE==1
    unsigned int arrSize,arrWidth;
#endif
    size_t outI=0;

    while(*format)
    {
        if(*format!='%')
        {
            outFls(*format,ptr,outI);
            ++outI;
            format++;
            continue;
        }
        else
        {
            format++;
        }
        flags=0U;
        do
        {
            switch(*format)
            {
                case '0':
                {
                    flags|=FLAGS_ZEROPAD;
                    format++;
                    break;
                }
                case '-':
                {
                    flags|=FLAGS_LEFT;
                    format++;
                    break;
                }
                case '+':
                {
                    flags|=FLAGS_PLUS;
                    format++;
                    break;
                }
                case ' ':
                {
                    flags|=FLAGS_SPACE;
                    format++;
                    break;
                }
                case '#':
                {
                    flags|=FLAGS_HASH;
                    format++;
                    break;
                }
                default :
                {
                    goto flagAnalyzeFinish;
                }
            }
        }while(1);
flagAnalyzeFinish:;
        //宽度部分处理
        if(*format=='*')
        {
            const int wi=va_arg(va,int);
            if(wi<0)
            {
                flags|=FLAGS_LEFT;
                width=(unsigned int)-wi;
            }
            else
            {
                width=(unsigned int)wi;
            }
            format++;
        }
        else
        {
            width=getUintFromStr(&format);
        }
        //精度处理
        if(*format=='.')
        {
            flags|=FLAGS_PRECISION;
            format++;
            if(*format=='*')
            {
                const int tmp=va_arg(va,int);
                precision=(tmp)>0?(unsigned int)(tmp):0U;
                format++;
            }
            else
            {
                precision=getUintFromStr(&format);
            }
        }
        else
        {
            precision=0U;
        }
#if HX_PRINTF_ARRAY_ENABLE==1
        //数组长度处理
        if(*format=='&')
        {
            flags|=FLAGS_ARR_LEN;
            format++;
            if(*format=='*')
            {
                const int tmp=va_arg(va,int);
                arrSize=(tmp)>0?(unsigned int)(tmp):0U;
                format++;
            }
            else
            {
                arrSize=getUintFromStr(&format);
            }
            if(*format=='^')
            {
                format++;
                if(*format=='*')
                {
                    const int tmp=va_arg(va,int);
                    arrWidth=(tmp)>0?(unsigned int)(tmp):0U;
                    format++;
                }
                else
                {
                    arrWidth=getUintFromStr(&format);
                }
            }
            else
            {
                arrWidth=arrSize;
            }
        }
        else
        {
            arrWidth=0U;
            arrSize=0U;
        }
#endif
        switch(*format)
        {
            case '%' :
            {
                outFls('%',ptr,outI);
                ++outI;
                format++;
                break;
            }
#if HX_PRINTF_CHAR_ENABLE==1
            case 'c' :
            {
                format++;
                if(flags&FLAGS_ARR_LEN)
                {
#if HX_PRINTF_ARRAY_CHAR_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                    printARR(char,printChar);
#endif
                }
                else
                {
                    outI=printChar(out,ptr,outI,fls,(char)va_arg(va,int32_t),width,flags);
                }
                break;
            }
#endif
#if HX_PRINTF_STRING_ENABLE==1
            case 'S' :
            {
                flags|=FLAGS_UPPER;
                format++;
                outI=printString(out,ptr,outI,fls,(const char*)va_arg(va,const char*),width,flags);
                break;
            }
            case 's' :
            {
                format++;
                outI=printString(out,ptr,outI,fls,(const char*)va_arg(va,const char*),width,flags);
                break;
            }
#endif
#if HX_PRINTF_INT32_ENABLE==1
            case 'd' :
            case 'i' :
            {
                goto handleDIUVX;
            }
#endif
#if HX_PRINTF_UINT32_ENABLE==1
            case 'u' :
            {
                goto handleDIUVX;
            }
#endif
#if HX_PRINTF_UINT32_BOX_ENABLE==1
            case 'x' :
            case 'X' :
            case 'b' :
            {
                goto handleDIUVX;
            }
#endif
#if HX_PRINTF_INT32_ENABLE==1||HX_PRINTF_UINT32_ENABLE==1||HX_PRINTF_UINT32_BOX_ENABLE==1
            case 'h' :
            {
                format++;
                if(*format=='h')
                {
                    format++;
                    flags|=FLAGS_HH;
                }
                else
                {
                    flags|=FLAGS_H;
                }
handleDIUVX:;
                switch(*format)
                {
#if HX_PRINTF_INT32_ENABLE==1
                    case 'd' :
                    case 'i' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_ENABLE==1
                            if(flags&FLAGS_H)
                            {
#if HX_PRINTF_ARRAY_INT16_ENABLE==1
                                printARR(int16_t,printInt32);
#endif
                            }
                            else if(flags&FLAGS_HH)
                            {
#if HX_PRINTF_ARRAY_INT8_ENABLE==1
                                printARR(int8_t,printInt32);
#endif
                            }
                            else
                            {
#if HX_PRINTF_ARRAY_INT32_ENABLE==1
                                printARR(int32_t,printInt32);
#endif
                            }
#endif
                        }
                        else
                        {
                            outI=printInt32(out,ptr,outI,fls,va_arg(va,int32_t),width,flags);
                        }
                        break;
                    }
#endif
#if HX_PRINTF_UINT32_ENABLE==1
                    case 'u' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_ENABLE==1
                            if(flags&FLAGS_H)
                            {
#if HX_PRINTF_ARRAY_UINT16_ENABLE==1
                                printARR(uint16_t,printUInt32);
#endif
                            }
                            else if(flags&FLAGS_HH)
                            {
#if HX_PRINTF_ARRAY_UINT8_ENABLE==1
                                printARR(uint8_t,printUInt32);
#endif
                            }
                            else
                            {
#if HX_PRINTF_ARRAY_UINT32_ENABLE==1
                                printARR(uint32_t,printUInt32);
#endif
                            }
#endif
                        }
                        else
                        {
                            outI=printUInt32(out,ptr,outI,fls,va_arg(va,uint32_t),width,flags);
                        }
                        break;
                    }
#endif
#if HX_PRINTF_UINT32_BOX_ENABLE==1
                    case 'x' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_ENABLE==1
                            if(flags&FLAGS_H)
                            {
#if HX_PRINTF_ARRAY_UINT16_ENABLE==1
                                printARRBOX(uint16_t,printUInt32BOX,4);
#endif
                            }
                            else if(flags&FLAGS_HH)
                            {
#if HX_PRINTF_ARRAY_UINT8_ENABLE==1
                                printARRBOX(uint8_t,printUInt32BOX,4);
#endif
                            }
                            else
                            {
#if HX_PRINTF_ARRAY_UINT32_ENABLE==1
                                printARRBOX(uint32_t,printUInt32BOX,4);
#endif
                            }
#endif
                        }
                        else
                        {
                            outI=printUInt32BOX(out,ptr,outI,fls,va_arg(va,uint32_t),width,flags,4);
                        }
                        break;
                    }
                    case 'X' :
                    {
                        format++;
                        flags|=FLAGS_UPPER;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_ENABLE==1
                            if(flags&FLAGS_H)
                            {
#if HX_PRINTF_ARRAY_UINT16_ENABLE==1
                                printARRBOX(uint16_t,printUInt32BOX,4);
#endif
                            }
                            else if(flags&FLAGS_HH)
                            {
#if HX_PRINTF_ARRAY_UINT8_ENABLE==1
                                printARRBOX(uint8_t,printUInt32BOX,4);
#endif
                            }
                            else
                            {
#if HX_PRINTF_ARRAY_UINT32_ENABLE==1
                                printARRBOX(uint32_t,printUInt32BOX,4);
#endif
                            }
#endif
                        }
                        else
                        {
                            outI=printUInt32BOX(out,ptr,outI,fls,va_arg(va,uint32_t),width,flags,4);
                        }
                        break;
                    }
                    case 'b' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_ENABLE==1
                            if(flags&FLAGS_H)
                            {
#if HX_PRINTF_ARRAY_UINT16_ENABLE==1
                                printARRBOX(uint16_t,printUInt32BOX,1);
#endif
                            }
                            else if(flags&FLAGS_HH)
                            {
#if HX_PRINTF_ARRAY_UINT8_ENABLE==1
                                printARRBOX(uint8_t,printUInt32BOX,1);
#endif
                            }
                            else
                            {
#if HX_PRINTF_ARRAY_UINT32_ENABLE==1
                                printARRBOX(uint32_t,printUInt32BOX,1);
#endif
                            }
#endif
                        }
                        else
                        {
                            outI=printUInt32BOX(out,ptr,outI,fls,va_arg(va,uint32_t),width,flags,1);
                        }
                        break;
                    }
#endif
                }
                break;
            }
#endif
#if HX_PRINTF_INT64_ENABLE==1||HX_PRINTF_UINT64_ENABLE==1||HX_PRINTF_UINT64_BOX_ENABLE==1||HX_PRINTF_FLOAT_ENABLE==1
            case 'l' :
            {
                format++;
handleLL:;
                switch(*format)
                {
                    case 'l' :
                    {
                        format++;
                        goto handleLL;
                    }
#if HX_PRINTF_INT64_ENABLE==1
                    case 'd' :
                    case 'i' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_INT64_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARR(int64_t,printInt64);
#endif
                        }
                        else
                        {
                            outI=printInt64(out,ptr,outI,fls,va_arg(va,int64_t),width,flags);
                        }
                        break;
                    }
#endif
#if HX_PRINTF_UINT64_ENABLE==1
                    case 'u' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_UINT64_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARR(uint64_t,printUInt64);
#endif
                        }
                        else
                        {
                            outI=printUInt64(out,ptr,outI,fls,va_arg(va,uint64_t),width,flags);
                        }
                        break;
                    }
#endif
#if HX_PRINTF_UINT64_BOX_ENABLE==1
                    case 'x' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_UINT64_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARRBOX(uint64_t,printUInt64BOX,4);
#endif
                        }
                        else
                        {
                            outI=printUInt64BOX(out,ptr,outI,fls,va_arg(va,uint64_t),width,flags,4);
                        }
                        break;
                    }
                    case 'X' :
                    {
                        format++;
                        flags|=FLAGS_UPPER;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_UINT64_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARRBOX(uint64_t,printUInt64BOX,4);
#endif
                        }
                        else
                        {
                            outI=printUInt64BOX(out,ptr,outI,fls,va_arg(va,uint64_t),width,flags,4);
                        }
                        break;
                    }
                    case 'b' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_UINT64_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARRBOX(uint64_t,printUInt64BOX,1);
#endif
                        }
                        else
                        {
                            outI=printUInt64BOX(out,ptr,outI,fls,va_arg(va,uint64_t),width,flags,1);
                        }
                        break;
                    }
#endif
#if HX_PRINTF_FLOAT_ENABLE==1
                    case 'f' :
                    {
                        format++;
                        if(flags&FLAGS_ARR_LEN)
                        {
#if HX_PRINTF_ARRAY_FLOAT_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                            printARRFLO(double,printFloat);
#endif
                        }
                        else
                        {
                            outI=printFloat(out,ptr,outI,fls,va_arg(va,double),width,precision,flags);
                        }
                        break;
                    }
#endif
                }
                break;
            }
#endif
#if HX_PRINTF_FLOAT_ENABLE==1
            case 'f' :
            {
                format++;
                if(flags&FLAGS_ARR_LEN)
                {
#if HX_PRINTF_ARRAY_FLOAT_ENABLE==1&&HX_PRINTF_ARRAY_ENABLE==1
                    printARRFLO(float,printFloat);
#endif
                }
                else
                {
                    outI=printFloat(out,ptr,outI,fls,va_arg(va,double),width,precision,flags);
                }
                break;
            }
#endif
            default :
            {
                outFls(*format,ptr,outI);
                ++outI;
                format++;
                break;
            }
        }

    }
    outFls(0,ptr,outI);
    return (int)

        outI;

}

INTERNAL_TEXT(fileLineStructPreTreat) void fileLineStructPreTreat(const char*file,int line,FileLineStruct*fls)
{
    if(file)
    {
        unsigned int fileLen=0;
        while(file[fileLen]){++fileLen;}
        if(fileLen>12)
        {
            file+=fileLen-12;
            fileLen=12;
        }
    }
    fls->file=file;
    fls->line=line;
    fls->length=12+5+1;
    fls->prevBuf=0;
}

EXTERNAL_TEXT(hxPrintfVFL) int hxPrintfVFL(const char*file,int line,const char*format,...)
{
#if defined(SCNS_SMCTP_ENABLE)&&SCNS_SMCTP_ENABLE==1
    if(SCNS_STATUS_OK!=scnsSmctpLockChannel(SCNS_SMCTP_CHANNEL_DEBUG)){return 0;}
#endif
    FileLineStruct fls;
    fileLineStructPreTreat(file,line,&fls);
    va_list va;
    va_start(va,format);
    const int ret=hxInnerPrintf(outChar,NULL,&fls,format,va);
    va_end(va);
#if defined(SCNS_SMCTP_ENABLE)&&SCNS_SMCTP_ENABLE==1
    scnsSmctpUnLockChannel(SCNS_SMCTP_CHANNEL_DEBUG);
#endif
    return ret;
}

EXTERNAL_TEXT(hxPrintf) int hxPrintf(const char*format,...)
{
#if defined(SCNS_SMCTP_ENABLE)&&SCNS_SMCTP_ENABLE==1
    if(SCNS_STATUS_OK!=scnsSmctpLockChannel(SCNS_SMCTP_CHANNEL_DEBUG)){return 0;}
#endif
    va_list va;
    va_start(va,format);
    const int ret=hxInnerPrintf(outChar,NULL,NULL,format,va);
    va_end(va);
#if defined(SCNS_SMCTP_ENABLE)&&SCNS_SMCTP_ENABLE==1
    scnsSmctpUnLockChannel(SCNS_SMCTP_CHANNEL_DEBUG);
#endif
    return ret;
}

EXTERNAL_TEXT(hxSNPrintf) int hxSNPrintf(char*buffer,size_t count,const char*format,...)
{
    OutBufWrap bufWrap={
        .buffer=buffer,
        .maxLen=count,
    };
    va_list va;
    va_start(va,format);
    const int ret=hxInnerPrintf(outBuf,&bufWrap,NULL,format,va);
    va_end(va);
    return ret;
}

EXTERNAL_TEXT(hxVSNPrintf) int hxVSNPrintf(char*buffer,size_t count,const char*format,va_list va)
{
    OutBufWrap bufWrap={
        .buffer=buffer,
        .maxLen=count,
    };
    return hxInnerPrintf(outBuf,&bufWrap,NULL,format,va);
}

EXTERNAL_TEXT(hxSPrintf) int hxSPrintf(char*buffer,const char*format,...)
{
    OutBufWrap bufWrap={
        .buffer=buffer,
        .maxLen=INT32_MAX,
    };
    va_list va;
    va_start(va,format);
    const int ret=hxInnerPrintf(outBuf,&bufWrap,NULL,format,va);
    va_end(va);
    return ret;
}

#if defined (_WIN32)||defined(__APPLE__)||defined(__linux__)

EXTERNAL_TEXT(hxFPrintf) int hxFPrintf(FILE*fp,const char*format,...)
{
    va_list va;
    va_start(va,format);
    const int ret=hxInnerPrintf(outFChar,fp,NULL,format,va);
    va_end(va);
    return ret;
}

#endif
